前置知识:

1)在Three.js中,相机的坐标系有两种:世界坐标系和相机坐标系。

世界坐标系(World Coordinate System):世界坐标系是一个固定的坐标系,用来表示场景中所有物体的位置和方向。在世界坐标系中,原点通常位于场景的中心,坐标轴的方向是固定的。

相机坐标系(Camera Coordinate System):相机坐标系是相对于相机的坐标系,原点位于相机的位置,坐标轴的方向是相对于相机朝向定义的。

假设我们有一个在世界坐标系中的三维物体,现在我们需要将其坐标转换到相机坐标系中,并最终投影到屏幕坐标系上。

假设物体的世界坐标为 (x, y, z),相机的视图矩阵为 M,投影矩阵为 P。

将物体的世界坐标转换到相机坐标系中:

物体相对于相机的坐标 = M * (x, y, z, 1) 其中,M为相机的视图矩阵,(x, y, z, 1)为物体在齐次坐标系中的坐标。
将相机坐标转换为屏幕坐标:

屏幕坐标 = P * (物体相对于相机的坐标) 其中,P为投影矩阵。
通过这些矩阵相乘的操作,我们可以将物体的世界坐标转换为屏幕坐标,然后在屏幕上进行渲染显示。在Three.js中,这些坐标系转换的细节通常由渲染引擎来处理,开发者只需要设置好相机的位置和视角,而不需要直接进行坐标系转换的计算。

  1. 相机种类:

正交相机(Orthographic Camera)和透视相机(Perspective Camera)是在计算机图形学中常用的两种相机模型,它们分别适用于不同的场景和效果。

-正交相机(Orthographic Camera)原理
正交相机是一种没有透视效果的相机模型。它总是以固定的大小显示物体,不管物体距离相机多远。这意味着不管物体离相机远近,它们的大小和比例都是相同的。这种相机模型通常用于需要精确测量或展示物体尺寸的场景,例如工程图或平面设计。

正交相机的投影是平行的,因此物体在投影平面上的大小不随距离的变化而变化。正交相机的投影矩阵是简单的正交矩阵,不考虑远近物体的透视变化。

-透视相机(Perspective Camera)原理
透视相机是一种模拟人眼看世界的相机模型。它在远处看起来较小,在近处看起来较大,这是因为它考虑了透视效果。根据透视原理,物体离相机越远,它们在投影平面上的大小就越小,这是为了模拟人眼在现实世界中看到的景象。

透视相机的投影是通过透视矩阵实现的,它考虑了物体到相机的距离,从而实现了远近物体的透视变化。透视相机通常用于需要模拟真实世界场景的场合,例如游戏、虚拟现实和电影特效等。

正交相机和透视相机分别适用于不同的场景和效果。正交相机适用于需要精确测量或展示物体尺寸的场景,而透视相机适用于模拟真实世界场景的场合。在Three.js中,可以通过创建不同类型的相机对象来使用正交相机和透视相机,根据场景需求选择合适的相机类型来实现不同的效果。
3)

相机的矩阵通常由相机的位置、朝向和投影参数来定义。在计算机图形学中,通常使用以下几种矩阵来表示相机的属性:

视图矩阵(View Matrix):视图矩阵定义了相机的位置和朝向。它将世界坐标系中的点变换到相机坐标系中。视图矩阵通常是一个 4x4 的矩阵,可以通过一系列的平移、旋转和缩放操作来构建。

投影矩阵(Projection Matrix):投影矩阵定义了相机的投影方式,包括透视投影和正交投影。它将相机坐标系中的点变换到裁剪空间中。投影矩阵也是一个 4x4 的矩阵,通常可以通过函数来创建透视投影矩阵或正交投影矩阵。

three.js 中的相机API和使用方法:

在Three.js中,相机是用来定义场景中的视角和视野范围的重要组件。以下是一些在Three.js中常用的相机属性:

position:相机的位置,即相机所在的三维空间坐标。

rotation:相机的旋转角度,用来控制相机的方向。

aspect:相机的宽高比,即渲染输出的宽度与高度之比。

near:相机的近裁剪面,指定了从相机到近裁剪面的距离范围内的物体将被渲染。

far:相机的远裁剪面,指定了从相机到远裁剪面的距离范围内的物体将被渲染。

zoom:相机的缩放比例。

matrixWorld:相机在世界坐标系中的变换矩阵。

projectionMatrix:相机的投影矩阵,用来将三维坐标转换为二维屏幕坐标。

fov:透视相机的视野角度,单位为度数。

left, right, top, bottom:正交相机的左右上下裁剪面。

这些属性可以通过创建不同类型的相机对象,如透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)来设置和调整。相机的这些属性可以根据需求来调整,以实现不同的视角和效果。

Three.js提供了不同类型的相机,例如透视相机(PerspectiveCamera)和正交相机(OrthographicCamera)。相机对象具有一些常见的属性,例如位置、方向、投影矩阵等。这些属性可以用来控制相机的位置、朝向和投影效果。

相机的详细使用方法
创建透视相机(PerspectiveCamera)
javascript

1
2
3
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
scene.add(camera);

创建正交相机(OrthographicCamera)
javascript

1
2
3
var camera = new THREE.OrthographicCamera(-2, 2, 2, -2, 1, 1000);
camera.position.set(0, 0, 5);
scene.add(camera);

控制相机的位置和方向
javascript

1
2
camera.position.set(0, 0, 5);
camera.lookAt(0, 0, 0);

设置相机的裁剪大小
javascript

1
2
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

将相机指向特定的位置
javascript

1
2
var target = new THREE.Vector3(0, 0, 0);
camera.lookAt(target);

控制相机的视野和焦距
javascript

1
2
3
4
5
camera.fov = 60;
camera.far = 1000;
camera.near = 0.1;
camera.updateProjectionMatrix();

监听相机的变化
javascript

1
2
3
4
5
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});

这些例子展示了如何使用Three.js中的相机,包括创建不同类型的相机、控制相机的位置和方向、设置投影矩阵、调整视野和焦距等操作。希望这些例子能够帮助您更好地理解和使用Three.js中的相机组件。

复杂点的例子

在Three.js中,可以通过设置相机的矩阵来实现一些复杂的相机变换效果,例如手动创建一个视图矩阵和投影矩阵,并将它们应用到相机中。以下是一个简单的例子,演示了如何手动创建一个视图矩阵和投影矩阵,然后将它们应用到相机中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 创建一个透视相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 手动设置视图矩阵
const viewMatrix = new THREE.Matrix4();
viewMatrix.lookAt(new THREE.Vector3(0, 0, 5), new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 1, 0));

// 手动设置投影矩阵
const projectionMatrix = new THREE.Matrix4();
projectionMatrix.perspective(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 将视图矩阵和投影矩阵应用到相机
camera.matrixAutoUpdate = false; // 禁止自动更新相机矩阵
camera.matrixWorld.copy(viewMatrix); // 应用视图矩阵到相机的世界矩阵
camera.projectionMatrix.copy(projectionMatrix); // 应用投影矩阵到相机的投影矩阵

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建场景
const scene = new THREE.Scene();

// 创建立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 渲染循环
function animate() {
requestAnimationFrame(animate);

// 使立方体旋转
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

// 渲染场景
renderer.render(scene, camera);
}

animate();